策略發想:
運用 兩檔兩檔台灣ETF 006208與00895 來進行投資組合建構
該策略使用 商品的短均與長均進行情境判讀,兩種商品 共有四種情境
依照四種情境不同,給予不同投資權重
策略名稱: sma_double_line
當兩個ETF短均都在長均之上,則進行 50% 50%的權重配置
當兩個ETF 短均都在長均之下,則進行15% 15% 的權重配置,剩下放現金
當一個ETF短均在長均上、一個短均在長均下時候,則進行50% 15%的權重配置
輸出結果:
**策略最新狀態
-------data1----------------
TW006208 持有股數: 5623
TW006208 持有成本: 79.28
-------data2----------------
TW00895 持有股數: 27456
TW00895 持有成本: 17.41
**
Backtrader : sma_double_line詳細程式碼
import yfinance as yf
import backtrader as bt
import datetime as dt
import matplotlib.pyplot as plt
import pandas as pd
#輸入資料
tw006208 = yf.Ticker('006208.TW')
df1=yf.download('006208.TW',start='2021-08-12',end='2022-2-14')
df1 = df1[['Open','High','Low','Close','Volume']]
df1.index= pd.to_datetime(df1.index)
df1.columns=['open','high','low','close','volume']
df1.fillna(0)
df1.to_csv('TW006208.csv')
tw00895 = yf.Ticker('00895.TW')
df2=yf.download('00895.TW',start='2021-08-12',end='2022-2-14')
df2 = df2[['Open','High','Low','Close','Volume']]
df2.index= pd.to_datetime(df2.index)
df2.columns=['open','high','low','close','volume']
df2.fillna(0)
df2.to_csv('TW00895.csv')
#創建策略:
class Sma_double_line(bt.SignalStrategy):
# list of parameters which are configurable for the strategy
params = dict(
pfast=10, # period for the fast moving average
pslow=30 # period for the slow moving average
)
def __init__(self):
self.d0_sma1 = bt.ind.SMA(self.data0.close,period=self.p.pfast) # data0 fast moving average
self.d0_sma2 = bt.ind.SMA(self.data0.close,period=self.p.pslow) # data0 slow moving average
self.d1_sma1 = bt.ind.SMA(self.data1.close,period=self.p.pfast) # data0 fast moving average
self.d1_sma2 = bt.ind.SMA(self.data1.close,period=self.p.pslow) # data0 slow moving average
#crossover = bt.ind.CrossOver(sma1, sma2) # crossover signal
def next(self):
if self.d0_sma1[0] > self.d0_sma2[0] and self.d1_sma1 > self.d1_sma2[0] :
self.order_target_percent(target=0.5,data='TW006208')
self.order_target_percent(target=0.5,data='TW00895')
if self.d0_sma1[0] < self.d0_sma2[0] and self.d1_sma1 < self.d1_sma2[0] :
self.order_target_percent(target=0.15,data='TW006208')
self.order_target_percent(target=0.15,data='TW00895')
if self.d0_sma1[0] > self.d0_sma2[0] and self.d1_sma1 < self.d1_sma2[0] :
self.order_target_percent(target=0.5,data='TW006208')
self.order_target_percent(target=0.15,data='TW00895')
if self.d0_sma1[0] < self.d0_sma2[0] and self.d1_sma1 > self.d1_sma2[0] :
self.order_target_percent(target=0.15,data='TW006208')
self.order_target_percent(target=0.5,data='TW00895')
#backtrader cerebro :
if __name__ == '__main__':
cerebro = bt.Cerebro(stdstats=False)
cerebro.addobserver(bt.observers.Value)
cerebro.addobserver(bt.observers.DrawDown)
datafeed1 = bt.feeds.PandasData(dataname=df1,name='TW006208')
datafeed2 = bt.feeds.PandasData(dataname=df2,name='TW00895')
cerebro.adddata(datafeed1)
cerebro.adddata(datafeed2)
cerebro.addstrategy(Sma_double_line)
cerebro.addsizer(bt.sizers.AllInSizer,percents=99)
cerebro.broker.setcash(3000000)
cerebro.run()
pos1 = cerebro.broker.getposition(datafeed1)
pos2 = cerebro.broker.getposition(datafeed2)
print('-------data1----------------')
print('TW006208 size:', pos1.size)
print('TW006208 price:', pos1.price)
print('-------data2----------------')
print('TW00895 size:', pos2.size)
print('TW00895 price:', pos2.price)
cerebro.plot(iplot=False,style='candlestick')
print('value:', cerebro.broker.get_value())
print('cash:', cerebro.broker.get_cash())